package vip.ola.pay.batchpay.yatoudf;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import vip.ola.core.common.constant.PayConstant;
import vip.ola.core.common.util.MyLog;
import vip.ola.core.common.util.PayDigestUtil;
import vip.ola.core.common.util.PayUtil;
import vip.ola.core.entity.AgentpayPassageAccount;
import vip.ola.core.entity.TransOrder;
import vip.ola.pay.channel.BaseTrans;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

import static vip.ola.core.common.constant.Constant.UTF8;
import static vip.ola.core.common.constant.PayEnum.ERR_0121;

/**
 * @author: dingzhiwei
 * @date: 17/12/25
 * @description:
 */
@Service
public class YatoudfTransService extends BaseTrans {

    private static final MyLog _log = MyLog.getLog(YatoudfTransService.class);

    @Override
    public String getChannelName() {
        return PayConstant.CHANNEL_NAME_ALIPAY;
    }

    public JSONObject trans(TransOrder transOrder) {
        JSONObject retObj = buildRetObj();
        try {
            _log.info("代付转账：" + transOrder.getChannelMchId());
            AgentpayPassageAccount payPassageAccount = rpcCommonService.rpcAgentpayPassageAccountService.findById(transOrder.getPassageAccountId());
            if (payPassageAccount == null || StringUtils.isBlank(payPassageAccount.getParam())) {
                return PayUtil.makeRetFail(ERR_0121);
            }
            JSONObject accountParams = JSONObject.parseObject(payPassageAccount.getParam());
            String mchId = payPassageAccount.getPassageMchId();
            String orderId = transOrder.getTransOrderId();
            String payUrl = accountParams.getString("payUrl");
            String channelNo = accountParams.getString("payCode");
            String privateKey = accountParams.getString("privateKey");
            String pay_notifyurl=accountParams.getString("notify_url");
            BigDecimal amount = new BigDecimal(transOrder.getAmount()).divide(new BigDecimal(100)).setScale(2);
            TreeMap<String, Object> obj = new TreeMap<>();
            obj.put("name", transOrder.getAccountName().trim());
            Long timeStamp = System.currentTimeMillis();
            obj.put("timestamp", timeStamp);
            obj.put("account", transOrder.getAccountNo().trim());
            obj.put("money", String.valueOf(amount));
            obj.put("mch_id",mchId);
            obj.put("currency","CNY");
            if ("支付宝".equals(transOrder.getBankName())){
                obj.put("type","2");
            }else {
                obj.put("type","1");
            }
            obj.put("address", "北京中关村");
            obj.put("notify_url", pay_notifyurl);
            obj.put("out_order_no", orderId);
            obj.put("channel", channelNo);
            obj.put("client_ip", "127.0.0.1");
            // 生成签名
            String queryBytes = getSign(obj, privateKey);
            obj.put("sign", queryBytes);
            _log.info("下单请求={}",JSONObject.toJSONString(obj));
            String respData = call(payUrl,obj);
            _log.info("下单结束respData->{}",respData);
            if (StringUtils.isNotBlank(respData)){
                JSONObject jsonObject = JSONObject.parseObject(respData);
                retObj.put("transOrderId", transOrder.getTransOrderId());
                if (jsonObject != null){
                    String code = jsonObject.getString("code");
                    if ("0".equals(code)  || "-100".equals(code)){
                        retObj.put("status",1);
                    }else {
                        retObj.put("status",3);
                        retObj.put("channelErrCode", code);
                        retObj.put("channelErrMsg", jsonObject.getString("msg"));
                    }
                }else {
                    retObj.put("status",1);
                    retObj.put("channelErrCode","E0001");
                    retObj.put("channelErrMsg","渠道返回异常，渠道返回为空");
                }
            }else {
                retObj.put("status",1);
                retObj.put("channelErrCode","E0008");
                retObj.put("channelErrMsg","下单异常，渠道返回为空");
            }

        } catch (Exception e) {
            e.printStackTrace();
            retObj.put("status",1);
            retObj.put("channelErrCode","E0009");
            retObj.put("channelErrMsg", e.getMessage());
        }
        return  retObj;
    }


    public static String call(String url, Map param) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
        // 响应模型
        CloseableHttpResponse response = null;
        String responseContext = null;
        try {
            StringEntity entity = new StringEntity(JSONObject.toJSONString(param), ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            if (responseEntity != null) {
                responseContext = EntityUtils.toString(responseEntity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContext;
    }

    public static String getSign(Map<String,Object> map, String key){
        ArrayList<String> list = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (null != entry.getValue() && !"".equals(entry.getValue())) {
                if (entry.getValue() instanceof JSONObject) {
                    list.add(entry.getKey() + "=" + PayDigestUtil.getSortJson((JSONObject) entry.getValue()) + "&");
                } else {
                    list.add(entry.getKey() + "=" + entry.getValue() + "&");
                }
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + key;
        _log.info("YatoudfTransService Sign Before MD5:" + result);
        result = PayDigestUtil.md5(result, UTF8);
        _log.info("YatoudfTransService Sign Result:" + result);
        return result;
    }



    public JSONObject query(TransOrder transOrder) {
        JSONObject retObj = buildRetObj();
        retObj.put("transOrderId", transOrder.getTransOrderId());
        try {
            AgentpayPassageAccount payPassageAccount = rpcCommonService.rpcAgentpayPassageAccountService.findById(transOrder.getPassageAccountId());
            if (payPassageAccount == null || StringUtils.isBlank(payPassageAccount.getParam())) {
                return PayUtil.makeRetFail(ERR_0121);
            }
            JSONObject accountParams = JSONObject.parseObject(payPassageAccount.getParam());
            String mchId = payPassageAccount.getPassageMchId();
            String orderId = transOrder.getTransOrderId();
            String queryUrl = accountParams.getString("queryUrl");
            String privateKey = accountParams.getString("privateKey");
            Map<String, Object> obj = new HashMap<>();
            Long timeStamp = System.currentTimeMillis();
            obj.put("timestamp", timeStamp);
            obj.put("mch_id",mchId);
            obj.put("type",0);
            obj.put("out_order_no", orderId);
            String queryBytes = getSign(obj, privateKey);
            obj.put("sign", queryBytes);
            _log.info("查询请求={}",JSONObject.toJSONString(obj));
            String respDetail = call(queryUrl,obj);
            _log.info("YatoudfTransService-》订单查询明细返回={}",respDetail);
            if (StringUtils.isNotEmpty(respDetail)){
                JSONObject jsonObject = JSONObject.parseObject(respDetail);
                if (jsonObject != null){
                    String code = jsonObject.getString("code");
                    if ("0".equals(code)){
                        String queryStatus = jsonObject.getJSONObject("data").getString("state");
                        if ("2".equals(queryStatus)){
                            retObj.put("status", 2);
                        }else if ("3".equals(queryStatus) ||"4".equals(queryStatus)||"5".equals(queryStatus) ){
                            retObj.put("status", 3);
                            retObj.put("channelErrCode", code);
                            retObj.put("channelErrMsg", jsonObject.getJSONObject("data").getString("msg"));
                        }else {
                            retObj.put("status", 1);
                        }
                    }else {
                        retObj.put("status", 3);
                        retObj.put("channelErrCode", code);
                        retObj.put("channelErrMsg", jsonObject.getJSONObject("data").getString("msg"));
                    }
                }else {
                    retObj.put("status", 1);
                    retObj.put("channelErrCode","E001");
                }
            }else {
                retObj.put("status", 1);
            }
        } catch (Exception e) {
            retObj.put("status", 1);
        }
        return  retObj;
    }



    @Override
    public JSONObject balance(String payParam) {
       try {
           JSONObject accountParams = JSONObject.parseObject(payParam);
           String mchId = "2644";
           String privateKey = accountParams.getString("privateKey");
           String balanceUrl = accountParams.getString("balanceUrl");
           Map<String, Object> obj = new HashMap<>();
           Long timeStamp = System.currentTimeMillis();
           obj.put("timestamp", timeStamp);
           obj.put("mch_id",mchId);
           String queryBytes = getSign(obj, privateKey);
           obj.put("sign", queryBytes);
           _log.info("查询请求={}",JSONObject.toJSONString(obj));
           String respData = call(balanceUrl,obj);
           _log.info("余额查询结束respData->{}",respData);
           if (StringUtils.isNotEmpty(respData)){
               JSONObject jsonObject = JSONObject.parseObject(respData);
               if (jsonObject != null){
                   String code = jsonObject.getString("code");
                   if ("0".equals(code)  ){
                       String totalAmt = jsonObject.getJSONObject("data").getString("balance");
                       JSONObject result = new JSONObject();
                       result.put("retCode","SUCCESS");
                       result.put("cashBalance",totalAmt);
                       return result;
                   }
               }
           }
       }catch (Exception e) {
           e.printStackTrace();
       }
       return null;
    }



}
